﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using backoffice.Data;
using System.Linq.Expressions;

namespace backoffice.Business
{
    public class BusinessZone
    {
        #region Create
        public static void createZone(Zone z)
        {
            try
            {
                dataZone.createZone(z);
            }
            catch (Exception e)
            {
                Messages.AddDebug(e.Message);
                throw new Exception("Error creating zone");
            }
        }

        public static void createZone(Country c, String name, String areas, String agriculturePratices)
        {
            try
            {
                Zone z = new Zone();
                z.CountryID = c.CountryID;
                z.Name = name;
                z.Areas = areas;
                z.AgriculturePractices = agriculturePratices;

                dataZone.createZone(z);
            }
            catch (Exception e)
            {
                Messages.AddDebug(e.Message);
                throw new Exception("Error creating zone");
            }
        }

        public static void createZone_Plant(Zones_Plant zp)
        {
            try
            {
                dataZone.createZone_Plant(zp);
            }
            catch (Exception e)
            {
                Messages.AddDebug(e.Message);
                throw new Exception("Error creating zone plants");
            }
        }

        public static void createZone_Plant(Zone z, Plant p, String plantingOnset, String plantingEnd, String plantingRate, String plantingRateUnit, String cycleLength, String harvestingOnset, String harvestingEnd)
        {
            try
            {
                Zones_Plant zp = new Zones_Plant();
                zp.ZoneID = z.ZoneID;
                zp.PlantID = p.PlantID;
                zp.PlantingOnset = plantingOnset;
                zp.PlantingEnd = plantingEnd;
                zp.PlantingRate = plantingRate;
                zp.PlantingRateUnit = zp.PlantingRateUnit;
                zp.CycleLength = cycleLength;
                zp.HarvestingOnset = harvestingOnset;
                zp.HarvestingEnd = harvestingEnd;

                dataZone.createZone_Plant(zp);
            }
            catch (Exception e)
            {
                Messages.AddDebug(e.Message);
                throw new Exception("Error creating zone plants");
            }
        }

        public static void createZone_Plant(Zone z, Plant p)
        {
            try
            {
                Zones_Plant zp = new Zones_Plant();
                zp.ZoneID = z.ZoneID;
                zp.PlantID = p.PlantID;

                dataZone.createZone_Plant(zp);
            }
            catch (Exception e)
            {
                Messages.AddDebug(e.Message);
                throw new Exception("Error creating zone plants");
            }
        }

        public static void createZoneCoordinates(Zone z, Dictionary<float, float> coords)
        {
            try
            {
                List<Coordinate> coordinates = new List<Coordinate>();

                foreach(KeyValuePair<float, float> co in coords){
                    BusinessCoordinate.createCoordinateForZone(co.Key, co.Value, z);
                }
            }
            catch (Exception e)
            {
                Messages.AddDebug(e.Message);
                throw new Exception("Error creating coordinates for zone");
            }
        }
        #endregion

        #region Get
        public static Zone getZone(Guid guid)
        {
            try
            {
                return dataZone.getZone(guid);
            }
            catch (Exception e)
            {
                Messages.AddDebug(e.Message);
                throw new Exception("Error getting zone");
            }
        }

        public static List<Zone> getZonesByCountry(Country c)
        {
            try
            {
                Expression<Func<Zone, bool>> whereClause = (Zone z) => z.CountryID == c.CountryID;

                return dataZone.getZones(whereClause).ToList();
            }
            catch (Exception e)
            {
                Messages.AddDebug(e.Message);
                throw new Exception("Error getting zone by country");
            }
        }


        public static List<Plant> getPlantsByZone(Zone z)
        {
            try
            {
                List<Plant> plants = new List<Plant>();

                Expression<Func<Zones_Plant, bool>> whereClause = (Zones_Plant zp) => (zp.ZoneID == z.ZoneID);
                List<Zones_Plant> zone_plants = dataZone.getZone_Plant(whereClause).ToList();

                foreach (Zones_Plant zp in zone_plants)
                {
                    Plant p = dataPlant.getPlant(zp.ZonePlantID);

                    if (!plants.Contains(p))
                    {
                        plants.Add(p);
                    }
                }

                return plants;
            }
            catch (Exception e)
            {
                Messages.AddDebug(e.Message);
                throw new Exception("Error getting plants by zone");
            }
        }

        public static Dictionary<Plant, Zones_Plant> getPlantsInfoByZone(Zone z)
        {
            try
            {
                Dictionary<Plant, Zones_Plant> plantsInfo = new Dictionary<Plant, Zones_Plant>();

                Expression<Func<Zones_Plant, bool>> whereClause = (Zones_Plant zp) => (zp.ZoneID == z.ZoneID);
                List<Zones_Plant> zone_plants = dataZone.getZone_Plant(whereClause).ToList();

                foreach (Zones_Plant zp in zone_plants)
                {
                    Plant p = dataPlant.getPlant(zp.ZonePlantID);

                    KeyValuePair<Plant, Zones_Plant> pair = new KeyValuePair<Plant, Zones_Plant>(p, zp);

                    if (!plantsInfo.Contains(pair))
                    {
                        plantsInfo.Add(p, zp);
                    }
                }

                return plantsInfo;
            }
            catch (Exception e)
            {
                Messages.AddDebug(e.Message);
                throw new Exception("Error getting plants and info by zone");
            }
        }

        public static List<Coordinate> getZoneCoordiantes(Zone z)
        {
            try
            {
                Expression<Func<Coordinate, bool>> whereClause = (Coordinate c) => (c.ZoneID == z.ZoneID);

                return dataCoordiante.getCoordinates(whereClause).ToList();
            }
            catch (Exception e)
            {
                Messages.AddDebug(e.Message);
                throw new Exception("Error getting zone coordinates");
            }
        }
        #endregion

        #region Set
        public static Boolean changeZone(Zone z)
        {
            try
            {
                return dataZone.changeZone(z);
            }
            catch (Exception e)
            {
                Messages.AddDebug(e.Message);
                throw new Exception("Error changing zone");
            }
        }
        #endregion

        #region Delete
        public static Boolean deleteZone(Zone z)
        {
            try
            {
                return dataZone.deleteZone(z);
            }
            catch (Exception e)
            {
                Messages.AddDebug(e.Message);
                throw new Exception("Error deletting zone");
            }
        }
        #endregion
    }
}
